package me.yuzho.study.concurrency.java8;

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;

/** We've already learned how to submit and run tasks once on an executor. 
 * In order to periodically run common tasks multiple times, we can utilize scheduled thread pools.
 * 
 * 为了按周期多次执行任务，我们可以使用scheduled线程池
 * @author yzhou-citrix
 *
 */
public class Case5ScheduledExecutors {
    
    public static void DemoScheduleOnce() throws InterruptedException {
        
        ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
        
        Runnable task = () -> System.out.println("Scheduling: " + System.nanoTime());
        ScheduledFuture<?> future = executor.schedule(task, 3, TimeUnit.SECONDS);
        
        TimeUnit.MILLISECONDS.sleep(1337);

        long remainingDelay = future.getDelay(TimeUnit.MILLISECONDS);
        System.out.printf("Remaining Delay: %sms\n", remainingDelay);
        
        executor.shutdown();
    }
    
    /**
     * scheduleAtFixedRate() doesn't take into account the actual duration of the task.
     */
    public static void DemoScheduleFixedRate() {
        ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);

        Runnable task = () -> System.out.println("Scheduling: " + System.nanoTime());

        int initialDelay = 0;
        int period = 1;
        executor.scheduleAtFixedRate(task, initialDelay, period, TimeUnit.SECONDS);
        
        //executor.shutdown();
    }
    
    /**
     * 
     */
    public static void DemoScheduleFixedDelay() {
        ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);

        Runnable task = () -> {
            try {
                TimeUnit.SECONDS.sleep(2);
                System.out.println("Scheduling: " + System.nanoTime());
            }
            catch (InterruptedException e) {
                System.err.println("task interrupted");
            }
        };

        int initialDelay = 0;
        int period = 1;
        executor.scheduleAtFixedRate(task, initialDelay, period, TimeUnit.SECONDS);
        
        //executor.shutdown();
    }

    public static void main(String[] args) throws InterruptedException {
        
        DemoScheduleFixedDelay();

    }

}
